package org.todo.dao;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.todo.domain.Todo;

/**
 * Implementation of TodoDao interface
 * @author Matthias Braunhofer
 */
public class TodoDaoImpl extends HibernateDaoSupport implements TodoDao {
    private static final String BASE_TODOS_QUERY = "from " + Todo.class.getName() + " t ";
    private static final String USER_TODOS_QUERY =  BASE_TODOS_QUERY + "where t.owner = ? order by t.creationDate desc";
    private static final String CATEGORY_TODOS_QUERY = BASE_TODOS_QUERY + "where t.category.id = ? order by t.creationDate desc";
    
    public List<Todo> findTodosForCategory(int categoryId) {
        return getHibernateTemplate().find(CATEGORY_TODOS_QUERY, categoryId);
    }

    public List<Todo> findTodosForUser(String username) {
        return getHibernateTemplate().find(USER_TODOS_QUERY, username);
    }

    public Todo getTodo(int todoId) {
        return (Todo)getHibernateTemplate().get(Todo.class, todoId);
    }

    public void saveTodo(Todo todo) {
        getHibernateTemplate().saveOrUpdate(todo);
    }

    public void deleteTodo(Todo todo) {
        getHibernateTemplate().delete(todo);
    }

    public List<Todo> searchTodos(String username, String searchText) {
        try {
            String searchQuery = "(" + searchText + ") AND (category.owner:Public OR category.owner:" + username + ")";
            String[] searchFields = {"title", "description", "owner", "creationDate", "dueDate", "category.name", "category.owner"};
            QueryParser parser = new MultiFieldQueryParser(searchFields, new StandardAnalyzer());
            org.apache.lucene.search.Query luceneQuery = parser.parse(searchQuery);
            FullTextSession ftSession = Search.getFullTextSession(getSession());
            org.hibernate.Query query = ftSession.createFullTextQuery(luceneQuery, Todo.class);
            return query.list();
        } catch (ParseException ex) {
            Logger.getLogger(TodoDaoImpl.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
}
